
//#include <ab_utils.hpp>
#include <ab_logger.hpp>
#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
#include "http_server.hpp"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>

#define LOCK_FILE "./rtos-agent.lock"

using json = nlohmann::json;
using namespace anbantech;


int lock_fd = -1;

void release_lock() {
    if (lock_fd != -1) {
        flock(lock_fd, LOCK_UN);
        close(lock_fd);
        lock_fd = -1;
        remove(LOCK_FILE);
    }
}

void signal_handler(int signum) {
    if (signum == SIGINT || signum == SIGTERM) {
        release_lock();
        exit(EXIT_SUCCESS);
    }
}

void create_lock() {
    lock_fd = open(LOCK_FILE, O_RDWR | O_CREAT | O_EXCL, 0640);
    if (lock_fd == -1) {
        fprintf(stderr, "无法创建进程锁文件: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    int ret = flock(lock_fd, LOCK_EX | LOCK_NB);
    if (ret == -1) {
        fprintf(stderr, "进程已经在运行中\n");
        exit(EXIT_FAILURE);
    }
}

void create_daemon() {
    pid_t pid;

    pid = fork();

    if (pid > 0) {
        exit(EXIT_SUCCESS);
    }

    if (setsid() < 0) {
        exit(EXIT_FAILURE);
    }

    signal(SIGHUP, SIG_IGN);

    pid = fork();
    if (pid > 0) {
        exit(EXIT_SUCCESS);
    }

//    chdir("/");

    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    open("/dev/null", O_RDONLY);
    open("/dev/null", O_WRONLY);
    open("/dev/null", O_RDWR);
}

int main(int argc,char** argv) {
    create_daemon();

    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    signal(SIGSEGV,signal_handler);
    signal(SIGKILL,signal_handler);

    create_lock();

//    SETLOGLEVEL(WARN);
    std::string cfg_path("../cfg/agent_cfg.json");
    if(argc == 2){
        if(access(argv[1],F_OK)==0)
            cfg_path=argv[1];
        else
            LOG(WARN,"%s not exists,use default ../cfg/agent_cfg.json",argv[1]);
    }
    if(access(cfg_path.c_str(),F_OK) != 0) {
        LOG(ERROR,"default cfg not exist");
        exit(1);
    }

    http_server server(cfg_path);
    if(server.init()==0)
        server.run();
    std::cout << "server init err" << std::endl;
    return 0;
}
